/**
 *  Copyright (C) 2008-2009  The Aceituna Project Team
 *  Portions of this code are Copyright(C) 2002-2007  The FreeCol Team (www.freecol.org).
 *
 *  This file is part of Aceituna Project.
 *
 *  Aceituna Project is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  Aceituna Project is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with Aceituna Project.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.aceitunaproject.mapdisplay.resources;

import java.awt.Component;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.io.File;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import com.aceitunaproject.mapdisplay.config.DisplayConfigurationProvider;
import com.aceitunaproject.mapdisplay.model.map.Direction;

/**
 * Provides scaled images to use when drawing the Map.
 * 
 * @author Federico Bergstein
 * 
 */
public class ImageLibrary {

	private static final String SEPARATOR = File.separator;
	
	private static final String IMAGEFOLDER = "C:\\Federico\\Code\\Images\\images_freecol";//DisplayConfigurationProvider
			//.getConfig().getImageFolder();
	private static final String IMAGEEXT = "png";//			.getConfig().getImageExt();


	private static final String EVEN = "even";
	private static final String ODD = "odd";

	/**
	 * Stores the images already required in memory to optimize disk access
	 */
	private static Map<String, Image> images = new HashMap<String, Image>();

	/**
	 * 
	 * Gets an image from the library.
	 * 
	 * @param name
	 *            the name of the image.
	 * @return the required image
	 */
	public static Image getImage(String name) {
		Image scIm;

		if (!images.containsKey(name)) {
			scIm = getScaledImage(IMAGEFOLDER + SEPARATOR + name + "." + IMAGEEXT);
			images.put(name, scIm);
		} else {
			scIm = images.get(name);
		}
		return scIm;
	}

	/**
	 * 
	 * returns the appropriate border tile image for a given tileType an
	 * direction, using the X and Y coordinates of the tile to alternate between
	 * versions of a given border and break possible patterns in the map that
	 * would cause a "checkered" or "ChessBoard" effect.
	 * 
	 * @param basicTileType
	 *            the basic tile type of the tile whose border image is required
	 * @param direction
	 *            the direction of the border
	 * @param x
	 *            the x coordinate of the tile
	 * @param y
	 *            the y coordinate of the tile
	 * @return the border tile image.
	 */
	public static Image getBorderTileImage(String basicTileType,
			Direction direction, int x, int y) {

		String breakPattern = EVEN;

		Image scIm;

		if ((x + y) % 2 != 0) {

			breakPattern = ODD;
		}
		if (!images.containsKey(basicTileType + direction.toString()
				+ breakPattern)) {

			scIm = getScaledImage(IMAGEFOLDER + SEPARATOR + "tiles" + SEPARATOR + basicTileType.toLowerCase()
					+ SEPARATOR + "border_" + direction.toString() + "_" + breakPattern
					+ "." + IMAGEEXT);

			images.put(basicTileType + breakPattern, scIm);
		} else {
			scIm = images.get(basicTileType + direction.toString()
					+ breakPattern);
		}
		return scIm;
	}

	/**
	 * 
	 * returns the appropriate tile image for a given tileType, using the X and
	 * Y coordinates of the tile to alternate between versions of a given border
	 * and break possible patterns in the map that would cause a "checkered" or
	 * "ChessBoard" effect.
	 * 
	 * @param basicTileType
	 *            the basic tile type of the tile.
	 * @param x
	 *            the x coordinate of the tile
	 * @param y
	 *            the y coordinate of the tile
	 * @return the border tile image.
	 */
	public static Image getBasicTileImage(String basicTileType, int x, int y) {

		String breakPattern;

		Image scIm;

		if (x / (y + 1) % 2 == 0) {
			// the pattern is mostly visible on ocean tiles
			// this is an attempt to break it up so it doesn't create big
			// stripes or chess-board effect
			breakPattern = "1";
		} else {
			breakPattern = "0";
		}

		if (!images.containsKey(basicTileType + breakPattern)) {

			scIm = getScaledImage(IMAGEFOLDER + SEPARATOR + "tiles" + SEPARATOR + basicTileType.toLowerCase()
					+ SEPARATOR + "center" + breakPattern + "." + IMAGEEXT);
			images.put(basicTileType + breakPattern, scIm);
		} else {
			scIm = images.get(basicTileType + breakPattern);
		}
		return scIm;
	}

	/**
	 * Gets an scaled image from a path.
	 * 
	 * @param path
	 *            the path of the image file
	 * @return
	 */
	private static Image getScaledImage(String path) {

		Component _c = new Component() {

			private static final long serialVersionUID = 1L;
		};

		int h = 0;
		int w = 0;
		//URL url = ImageLibrary.class.getResource(path);
		Image im = Toolkit.getDefaultToolkit().getImage(path);

		h = im.getHeight(null);
		w = im.getWidth(null);
		Image scIm;

		MediaTracker mt = new MediaTracker(_c);

		scIm = im.getScaledInstance(w, h, Image.SCALE_SMOOTH);
		mt.addImage(scIm, 0, w, h);
		try {
			mt.waitForID(0);
		} catch (InterruptedException e) {
			return null;
		}
		return scIm;
	}
}
